/**
 * @brief TCP服务器
 * @version 1.0
 * @author 宋炜
 * @date 2023-8-28
 */

#pragma once

#include <netinet/in.h>

#include <string>
#include <atomic>
#include <mutex>
#include <functional>

#include "dataCh.hpp"
#include "tcpConnection.hpp"

#include "ipaddr.hpp"

class tcpServer : public dataCh
{
public:
	struct stConnItem
	{
		mandaravaIP_addr   m_peer__;
		bool operator==( const stConnItem& b ){
			char rst[ 40 ] , rstb[ 40 ] , * rc = nullptr , * rcb = nullptr;
#if USE_IPV6 == 1
			rc = inet_ntop( AF_INET6 , &b.m_peer__ , rst );
			rcb = inet_ntop( AF_INET6 , &m_peer__ , rstb );
#else
			rc = inet_ntop( AF_INET , &b.m_peer__, rst );
			rcb = inet_ntop( AF_INET , &m_peer__ , rstb );
#endif

			if( rc && rcb ){
				int r = strcpy( rc , rcb );
				if( r == 0 ){
#if USE_IPV6 == 1
					if( m_peer__.sin6_port == b.m_peer__.sin6_port ) return true;
					else return false;
#else
					if( m_peer__.sin_port == b.m_peer__.sin_port ) return true;
					else return false;
#endif
					
				}else{
					return false;
				}
			}

			throw std::runtime_error( "转换IP地址操作错误" );
		}
		bool operator<( const stConnItem& b){
			char rst[ 40 ] , rstb[ 40 ] , * rc = nullptr , * rcb = nullptr;
#if USE_IPV6 == 1
			rc = inet_ntop( AF_INET6 , &b.m_peer__ , rst );
			rcb = inet_ntop( AF_INET6 , &m_peer__ , rstb );
#else
			rc = inet_ntop( AF_INET , &b.m_peer__, rst );
			rcb = inet_ntop( AF_INET , &m_peer__ , rstb );
#endif

			if( rc && rcb ){
				int r = strcpy( rc , rcb );
				if( r < 0 ){
					return true;
				}else if( r > 0 ){
					return false;
				}else{
#if USE_IPV6 == 1
					if( m_peer__.sin6_port < b.m_peer__.sin6_port ) return true;
					else return false;
#else
					if( m_peer__.sin_port < b.m_peer__.sin_port ) return true;
					else return false;
#endif
				}
			}

			throw std::runtime_error( "转换IP地址操作错误" );
		}

		bool operator( const stConnItem& b){
			char rst[ 40 ] , rstb[ 40 ] , * rc = nullptr , * rcb = nullptr;
#if USE_IPV6 == 1
			rc = inet_ntop( AF_INET6 , &b.m_peer__ , rst );
			rcb = inet_ntop( AF_INET6 , &m_peer__ , rstb );
#else
			rc = inet_ntop( AF_INET , &b.m_peer__, rst );
			rcb = inet_ntop( AF_INET , &m_peer__ , rstb );
#endif

			if( rc && rcb ){
				int r = strcpy( rc , rcb );
				if( r > 0 ){
					return true;
				}else if( r < 0 ){
					return false;
				}else{
#if USE_IPV6 == 1
					if( m_peer__.sin6_port > b.m_peer__.sin6_port ) return true;
					else return false;
#else
					if( m_peer__.sin_port > b.m_peer__.sin_port ) return true;
					else return false;
#endif
				}
			}

			throw std::runtime_error( "转换IP地址操作错误" );
		}
	};
private:
	std::atomic< int >     m_fd__;            // 监听的句柄
	std::string            m_listen_addr__;   // 监听的IP地址
	std::atomic<uint16_t>  m_listen_port__;   // 监听的端口
	struct sockaddr_in6    m_addr6__;
	struct sockaddr_in     m_addr__;
	
	std::mutex             m_mutex__;

	std::map< stConnItem , std::shared_ptr<tcpConnection> >  m_clients__;

private:

public:
	tcpServer();
	tcpServer( const std::string& ip , uint16_t port );
	virtual ~tcpServer();
	bool listen();
	bool listen( const std::string& ip , uint16_t port );
	
	virtual nativeH_t native_handle() final{ return m_fd__.load(); }
	/**
	 * @brief 处理连接请求。接受连接后发出连接成功通知，通知参数提供新的连接对象指针
	 */
	virtual void onReadyRead( const uint8_t* data , size_t len ) final;
	
};
